﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TextList : MonoBehaviour
{
	public delegate void SelectCB(int index);



	// Properties

	[SerializeField]
	SpriteRenderer	m_indicator;					// 화살표
	[SerializeField]
	TextMesh		m_textMeshOriginal;				// 리스트를 구성할 텍스트메시 (오리지널)

	[SerializeField]
	float			m_cellSize;						// 각 셀마다 y축 크기
	[SerializeField]
	int				m_cellCountInOneScreen;			// 한번에 보여줄 셀 최대 갯수 (실제로 클리핑하지는 않고 스크롤 기준이 됨)



	// Members

	SmoothMoving	m_slideMover;					// 이 슬라이드 본체를 움직임
	SmoothMoving	m_indMover;						// 화살표를 움직임

	Vector3			m_slideOrigPos;					// 원래 위치
	Vector3			m_indOrigPos;

	List<TextMesh>	m_listItems;					// 리스트 아이템

	int				m_scrollStartIndex	= -1;		// 스크롤 시작 인덱스
	int				m_scrollEndIndex	= -1;		// 스크롤 종료 인덱스
	bool			m_needListScroll	= false;	// 리스트 스크롤이 필요한지 (false면 스크롤 없이 인덱스 표시만 움직임)


	/// <summary>
	/// 현재 인덱스
	/// </summary>
	public int currentIndex
	{
		get;
		private set;
	}


	public int itemCount
	{
		get
		{
			return m_listItems.Count;
		}
	}


	// Event handlers

	/// <summary>
	/// 아이템 선택시 이벤트
	/// </summary>
	public event SelectCB	Selected;

	bool isAwake		= false;

	void Awake()
	{
		if(isAwake)
			return;
		isAwake			= true;

		m_slideMover	= GetComponent<SmoothMoving>();					// SmoothMoving을 구한다
		m_indMover		= m_indicator.GetComponent<SmoothMoving>();

		m_slideOrigPos	= m_slideMover.transform.localPosition;			// 위치 구해두기
		//Debug.Log (m_slideOrigPos);
		m_indOrigPos	= m_indMover.transform.localPosition;

		m_textMeshOriginal.gameObject.SetActive(false);					// 아이템 원본이 되는 오브젝트는 꺼둔다
	}

	/// <summary>
	/// 텍스트 항목으로 리스트를 채운다
	/// </summary>
	/// <param name="textList"></param>
	public void SetList(IList<string> textList)
	{
		Awake ();

		m_listItems				= new List<TextMesh>();

		int count				= textList.Count;
		Transform listT			= transform;
		for (int i = 0; i < count; i++)
		{
			GameObject newItem	= Instantiate(m_textMeshOriginal.gameObject) as GameObject;
			newItem.SetActive(true);

			Transform itemT		= newItem.transform;
			itemT.parent		= listT;
			itemT.localPosition	= new Vector3(0, -m_cellSize * i);

			TextMesh textMesh	= newItem.GetComponent<TextMesh>();
			textMesh.text		= textList[i];
			m_listItems.Add(textMesh);
		}

		CalcScrollArea();
		//SetCursorTo(0, true);
		SetCursorTo(0);
	}

	/// <summary>
	/// 스크롤 영역, 스크롤 필요한지 여부 계산
	/// </summary>
	void CalcScrollArea()
	{
		int count			= itemCount;
		m_needListScroll	= itemCount > m_cellCountInOneScreen;

		if (m_needListScroll)
		{
			m_scrollStartIndex	= m_cellCountInOneScreen / 2;
			m_scrollEndIndex	= (m_cellCountInOneScreen - m_scrollStartIndex) + (count - m_cellCountInOneScreen);

			//Debug.Log(string.Format("scroll start index : {0} end index : {1}", m_scrollStartIndex, m_scrollEndIndex));
		}
	}

	/// <summary>
	/// 커서 위치시키기
	/// </summary>
	/// <param name="index"></param>
	/// <param name="silent">true일 경우 이벤트를 발생시키지 않음</param>
	public void SetCursorTo(int index, bool silent = false)
	{
		//Debug.Log (m_slideOrigPos);
		//int oldIndex				= currentIndex;
		currentIndex				= index;
		m_indMover.targetPosition	= new Vector3(m_indOrigPos.x, m_indOrigPos.y - m_cellSize * index);

		if (m_needListScroll)
		{
			if (m_scrollStartIndex >= index)				// * 맨 처음으로 스크롤
			{
				//Debug.Log (1);
				m_slideMover.targetPosition	= m_slideOrigPos;
			}
			else if (m_scrollEndIndex <= index)				// * 맨 마지막으로 스크롤
			{
				//Debug.Log (2);
				Vector3 endOfList	= m_slideOrigPos;
				endOfList.y			= endOfList.y + (m_scrollEndIndex - m_scrollStartIndex - 1) * m_cellSize;
				m_slideMover.targetPosition	= endOfList;
			}
			else
			{												// * 중간 지점 스크롤
				//Debug.Log (3);
				Vector3 targetPos	= m_slideOrigPos;
				targetPos.y			= m_slideOrigPos.y + (index - m_scrollStartIndex) * m_cellSize;
				m_slideMover.targetPosition	= targetPos;
			}
		}
		else
		{
			m_slideMover.targetPosition	= m_slideOrigPos;
		}

		//Debug.Log (m_slideMover.targetPosition);

		if(!silent && Selected != null)						// 이벤트 
			Selected(index);
	}



	void Update()
	{
		if (Input.GetKeyDown(KeyCode.UpArrow))				// * 위 화살표로 리스트 위로
		{
			if (currentIndex > 0)
				SetCursorTo(currentIndex - 1);
		}
		else if (Input.GetKeyDown(KeyCode.DownArrow))		// * 아래 화살표로 리스트 아래로
		{
			if (currentIndex < itemCount - 1)
				SetCursorTo(currentIndex + 1);
		}
	}
}
